#include "qca_driver.h"
#include "main.h"
static const char *TAG = "qca-driver";

/* The struct to hold all QCA7k and SPI related information */
qcaspi_t qca = {0};

extern void qcaspi_spi_thread(void *data);
extern void qca_network_thread(void *data);
static void qca_reset(void);
static void qca_wait_sync(void);

void qca_send(void *data, size_t len)
{
    if (len < QCAFRM_ETHMINLEN)
        len = QCAFRM_ETHMINLEN;

    NetworkBufferDescriptor_t *txDesc = NULL;
    txDesc                            = pvPortMalloc(sizeof(NetworkBufferDescriptor_t));
    txDesc->pucEthernetBuffer         = pvPortMalloc(len + QCAFRM_FRAME_OVERHEAD);
    txDesc->xDataLength               = len;
    memcpy(txDesc->pucEthernetBuffer + QCAFRM_HEADER_LEN, data, len);

    if (qca.task_handle == NULL)
		{
			//ESP_LOGE(TAG, "Task Handle NULL");
		}

    xQueueSend(qca.txQueue, &txDesc, 0);
    xTaskNotify(qca.task_handle, QCAGP_TX_FLAG, eSetBits);
}

void qca_irq_handler(void *arg)//gpio 外部中断 （上升沿触发）
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    xTaskNotifyFromISR(qca.task_handle, QCAGP_INT_FLAG, eSetBits, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if(GPIO_Pin == QCA7005_GPIO_INTERRUPT_Pin)
    {
        qca_irq_handler(NULL);
    }
}
void qca_ll_init(void)
{
    qca.sync    = QCASPI_SYNC_UNKNOWN;
    qca.txQueue = xQueueCreate(25, sizeof(NetworkBufferDescriptor_t *));
    qca.rxQueue = xQueueCreate(25, sizeof(NetworkBufferDescriptor_t *));
    QcaFrmFsmInit(&qca.lFrmHdl);

    /* QCA7000 reset pin setup */
    //gpio_reset_pin(QCASPI_RST);
    //gpio_set_direction(QCASPI_RST, GPIO_MODE_OUTPUT);
    
    qca_reset();

    //ESP_LOGI(TAG, "QCA Driver Init Success.");
    xTaskCreate(qcaspi_spi_thread, "qca_spi", 4096, &qca, tskIDLE_PRIORITY + 10, &qca.task_handle);
   // xTaskCreate(qca_network_thread, "qca_network", 4096, &qca, tskIDLE_PRIORITY + 8, NULL);

    /* Wait for sync. */
    qca_wait_sync();
}

void qca_reset(void)
{
    HAL_GPIO_WritePin(QCA7005_RESET_GPIO_Port,QCA7005_RESET_Pin,GPIO_PIN_RESET);
    vTaskDelay(100);
    HAL_GPIO_WritePin(QCA7005_RESET_GPIO_Port,QCA7005_RESET_Pin,GPIO_PIN_SET);
}

void qca_wait_sync(void)
{
    while (qca.sync != QCASPI_SYNC_READY) { vTaskDelay(pdMS_TO_TICKS(500)); }
}
